﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using DoeObjects;
using System.Collections.Generic;

namespace DoeLibsTest
{

    [TestClass]
    public class Author_Test
    {
        [TestInitialize]
        public void initializeDatabaseConnection()
        {
            TestContext.initialize();
        }

        /// <summary>
        /// tests to add a new author
        /// </summary>
        [TestMethod]
        public void test_add()
        {
            List<Author> authorsBeforeAdd = Author.getAll();

            Author newAuthor = Helper.createAuthorObject(false);

            int newAuthorId = Author.add(newAuthor);
            if (newAuthorId > 0)
            {

                List<Author> authorsAfterSave = Author.getAll();

                //test that it really gets added
                Assert.AreEqual(authorsBeforeAdd.Count + 1, authorsAfterSave.Count, string.Format("Author could not be added (listsize difference is not OK ({0}:{1}))", authorsBeforeAdd.Count, authorsAfterSave.Count));

                //test if the given id is ok
                Author savedAuthor = Author.getByAid(newAuthorId);
                Assert.AreEqual(newAuthor.Name, savedAuthor.Name);
            }
            else
            {
                Assert.Fail("Author could not be added");
            }
        }

        /// <summary>
        /// tests to update a existing author
        /// </summary>
        [TestMethod]
        public void test_update()
        {
            List<Author> authorsBeforeUpdate = Author.getAll();

            if (authorsBeforeUpdate.Count > 0)
            {
                //take first author:
                int authorId = authorsBeforeUpdate[0].Aid;

                Author author = Helper.createAuthorObject(false);

                if (Author.update(author))
                {
                    Assert.Fail("you cannot update an non author with no valid authorId");
                }

                author.Aid = authorId;

                if (Author.update(author))
                {
                    Author updatedAuthor = Author.getByAid(authorId);

                    Assert.AreEqual(author.Name, updatedAuthor.Name);
                }
                else
                {
                    Assert.Fail("could not update author");
                }
            }
        }

        /// <summary>
        /// tests to save a new author
        /// </summary>
        [TestMethod]
        public void test_saveNew()
        {
            List<Author> authorsBeforeAdd = Author.getAll();

            Author newAuthor = Helper.createAuthorObject(false);

            if (newAuthor.save())
            {
                //check that he was added...
                List<Author> authorsAfterAdd = Author.getAll();
                Assert.AreEqual(authorsBeforeAdd.Count + 1, authorsAfterAdd.Count, string.Format("Author could not be added (listsize difference is not OK ({0}:{1}))", authorsBeforeAdd.Count, authorsAfterAdd.Count));

                //if he was added, load him and compare him
                int authorId = newAuthor.Aid;
                if (authorId > 0)
                {

                    Author loadedAuthor = Author.getByAid(authorId);

                    Assert.AreEqual(newAuthor.Name, loadedAuthor.Name);
                }
                else
                {
                    Assert.Fail("AuthorId was not updated");
                }

            }
            else
            {
                Assert.Fail("could not save author");
            }
        }

        /// <summary>
        /// tests to save an existing author
        /// </summary>
        [TestMethod]
        public void test_saveExisting()
        {
            List<Author> authorsBeforeUpdate = Author.getAll();

            if (authorsBeforeUpdate.Count > 0)
            {
                Author authorToUpdate = authorsBeforeUpdate[0];
                authorToUpdate.Name = "update " + Helper.getRandomString();

                if (authorToUpdate.save())
                {
                    //check that he was added...
                    List<Author> authorsAfterUpdate = Author.getAll();
                    Assert.AreEqual(authorsBeforeUpdate.Count, authorsAfterUpdate.Count, string.Format("Author could not be added (listsize difference is not OK ({0}:{1}))", authorsBeforeUpdate.Count, authorsAfterUpdate.Count));

                    //if he was added, load him and compare him
                    int authorId = authorToUpdate.Aid;
                    if (authorId > 0)
                    {

                        Author loadedAuthor = Author.getByAid(authorId);

                        Assert.AreEqual(authorToUpdate.Name, loadedAuthor.Name);
                    }
                    else
                    {
                        Assert.Fail("AuthorId was not ok");
                    }

                }
                else
                {
                    Assert.Fail("could not save author");
                }
            }
        }

        [TestMethod]
        public void test_getById()
        {
            Author a = Helper.createAuthorObject(true);

            if (a != null)
            {
                Author loaded = Author.getByAid(a.Aid);

                Assert.AreEqual(a.Name, loaded.Name);
                Assert.AreEqual(a.Aid, loaded.Aid);
            }
            else
            {
                Assert.Fail("could not save author");
            }
        }

        [TestMethod]
        public void test_getAll()
        {
            List<Author> authorsBeforeAdd = Author.getAll();

            Author a = Helper.createAuthorObject(true);

            //save author again as a new one
            a.Aid = 0;
            a.save();

            List<Author> authorsAfterAdd = Author.getAll();

            Assert.AreEqual(authorsBeforeAdd.Count + 2, authorsAfterAdd.Count);
        }


        [TestMethod]
        public void test_getByName()
        {
            Author addedAuthor = Helper.createAuthorObject(true);

            List<Author> authorsWithSameName = Author.getByName(addedAuthor.Name, false);
            if (authorsWithSameName.Count > 0) 
            {
                foreach (Author author in authorsWithSameName)
                {
                    Assert.AreEqual(addedAuthor.Name, author.Name);
                }
            }
            else
            {
                Assert.Fail("Didn't find the new author");
            }
        }

        [TestMethod]
        public void test_getByNameLike()
        {
            Author addedAuthor = new Author();
            addedAuthor.Name = "Name " + Helper.getRandomString();

            //save author
            addedAuthor.save();

            List<Author> authorsWithSameName = Author.getByName("name", true);
            if (authorsWithSameName.Count > 0)
            {
                foreach (Author author in authorsWithSameName)
                {
                    Assert.IsTrue(author.Name.StartsWith("name"));
                }
            }
            else
            {
                Assert.Fail("Didn't find the new author");
            }
        }

        [TestMethod]
        public void test_getAuthorsFromTitle()
        {
            //add 2 new authors
            Author addedAuthor1 = Helper.createAuthorObject(true);

            Author addedAuthor2 = Helper.createAuthorObject(true);

            //create title:
            Publisher pub = new Publisher();
            pub.Name = Helper.getRandomString();
            if (!pub.save())
            {
                Assert.Fail("publisher could not be saved");
            }

            Title title = new Title();
            title.BookTitle = Helper.getRandomString();
            title.EditionNumber = 1;
            title.EditionYear = 1;
            title.FirstEditionYear = 1;
            title.ISBN10 = Helper.getRandomString().Substring(0,10);
            title.ISBN13 = Helper.getRandomString().Substring(0, 13);
            title.Publisher = pub;
            if (!title.save())
            {
                Assert.Fail("title could not be saved");
            }

            Title.addAuthor(addedAuthor1.Aid, title.TitleId, false);
            Title.addAuthor(addedAuthor2.Aid, title.TitleId, false);

            List<Author> titleAuthors = Author.getAuthorsFromBook(title.TitleId);

            Assert.AreEqual(2, titleAuthors.Count);
        }
    }
}
